//    Copyright (C) Kherty.  All rights reserved.

using System;
using OpenLS.Spreadsheet.Expressions;

namespace OpenLS.Spreadsheet.Formats.Biff.Tokens
{
    internal class RefNToken : FormulaToken
    {
        private readonly AccessorType _type;

        private RgceLocRel RgceLocRel;

        public RefNToken(AccessorType type)
        {
            _type = type;
        }

        public RefNToken(ushort rowIndex, short columnIndex, bool isRelativeRow, bool isRelativeColumn,
                         AccessorType accessType) : this(accessType)
        {
            RgceLocRel = new RgceLocRel(rowIndex, columnIndex, isRelativeRow, isRelativeColumn);
        }

        public override FormulaTokenId TokenId
        {
            get
            {
                switch (_type)
                {
                    case AccessorType.Array:
                        return FormulaTokenId.RefNA;
                    case AccessorType.Reference:
                        return FormulaTokenId.RefN;
                    case AccessorType.Value:
                        return FormulaTokenId.RefNV;
                    default:
                        throw new NotSupportedException();
                }
            }
        }

        /*private bool absoluteColumn;
        private bool absoluteRow;
        private int columnIndex;
        private int rowIndex;*/

        public override ushort GetLength(FormulaReadContextType formulaReadContextType)
        {
            return 4;
        }

        internal override void ReadContent(FormulaReadContext context)
        {
            RgceLocRel.Read(context.Reader);
            /*ushort r = context.ReadUInt16();
            // rowIndex = context.ReadUInt16();
            AddressHelper.ReadColumnAndFlags16(context.Reader, out columnIndex, out absoluteColumn, out absoluteRow);
            if (!absoluteRow)
                rowIndex = (short) r;
            else
                rowIndex = r;
             * */
        }

        public override void WriteContent(FormulaWriteContext context)
        {
            RgceLocRel.Write(context.Writer);
        }

        internal override Expression GetExpression(FormulaEvaluationContext context)
        {
            Worksheet ws = context.Worksheet;
            CellReferenceExpression result;
            if (context.InConditionalFormatting)
            {
                var cr = ReferenceHelper.GetAnchoredColumnReference(ws, RgceLocRel, context.Target);
                var rr = ReferenceHelper.GetAnchoredRowReference(ws, RgceLocRel, context.Target);

                result = new CellReferenceExpression(new StaticCellReference(rr, cr), ws);
                return result;
            }
            else
            {
                var rr = new FloatingRowReference(ws, (short) RgceLocRel.RowIndex, RgceLocRel.IsAbsoluteRow);
                FloatingColumnReference cr = ReferenceHelper.GetFloatingColumnReference(ws, RgceLocRel, context.Target);

                result = new CellReferenceExpression(new StaticCellReference(rr, cr), ws);
                return result;
            }
        }
    }
}